#include "base/uncopyable.hpp"
#include "event/loop.hpp"
#include "network/buffered_fd.hpp"
#include "network/byte_stream.hpp"

namespace ibox::network {
using namespace ibox::base;

class StdinStream : public Uncopyable, public ByteStream {
public:
    explicit StdinStream(event::Loop *loop);

public:
    void set_receive_callback(ReceiveCallback cb, size_t threshold) override;
    bool send(const void *data_ptr, size_t data_size) override {
        return false;
        (void) data_ptr;
        (void) data_size;
    }
    void bind(ByteStream *receiver) override { m_buffd.bind(receiver); }
    void unbind() override { m_buffd.unbind(); }

    bool enable();
    bool disable();

private:
    BufferedFd m_buffd;
};

class StdoutStream : public Uncopyable, public ByteStream {
public:
    explicit StdoutStream(event::Loop *loop);

public:
    void set_receive_callback(ReceiveCallback cb, size_t threshold) override {
        (void) cb;
        (void) threshold;
    }
    bool send(const void *data_ptr, size_t data_size) override;
    void bind(ByteStream *receiver) override { (void) receiver; }
    void unbind() override {}

    bool enable();
    bool disable();

private:
    BufferedFd m_buffd;
};

class StdioStream : public Uncopyable, public ByteStream {
public:
    explicit StdioStream(event::Loop *loop);

public:
    void set_receive_callback(ReceiveCallback cb, size_t threshold) override;
    bool send(const void *data_ptr, size_t data_size) override;
    void bind(ByteStream *receiver) override { m_in_buffd.bind(receiver); }
    void unbind() override { m_in_buffd.unbind(); }

    bool enable();
    bool disable();

private:
    BufferedFd m_in_buffd;
    BufferedFd m_out_buffd;
};

} // namespace ibox::network
